/**
 * RecvFileCmd.java
 * 版权所有(C) 2013
 * 创建者:cuiran 2013-11-27 下午3:39:14
 */
package com.ghyf.mplay.net.common;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.ghyf.mplay.application.CookieConstants;
import com.ghyf.mplay.application.UserInfoSingleton;
import com.ghyf.mplay.net.data.ConfigFtpData;
import com.ghyf.mplay.util.LogUtil;
import com.ghyf.mplay.value.ConstantValue;

/**
 *  文件传送
 * @author cuiran
 * @version 1.0.0
 */
public class RecvFileCmd extends RecvBase implements Runnable {
	/**
	 * 进度条<br>
	 */
	public static int progress=0;
	
	public RecvFileCmd(int listenPort, int serverPort,Context context){
		port_listen = listenPort;
		port_server = serverPort;
		mContext=context;
	}
	 short cmdID;
	 int timestamp;
	 int tickCount;
	 DatagramSocket so_out=null;
	 InetAddress inetAddr_in=null;
	 
	 DatagramSocket so_out_temp=null;
	 InetAddress inetAddr_in_temp=null;
	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		LogUtil.i(TAG, "RecvFileCmd.run() -- start!");
		try
		{
			LogUtil.i(TAG, "RecvFileCmd.run() -- try....");
			
			 so_out = new DatagramSocket();
			DatagramSocket so_in = new DatagramSocket(port_listen);
			
			
			LogUtil.i(TAG, "RecvFileCmd.run() -- Recv Socket Created!");
			so_in.setSoTimeout(100);
			
			byte[] buf_in = new byte[GData.maxPacketLength];
			DatagramPacket pkt_in = new DatagramPacket(buf_in, buf_in.length);
			LogUtil.i(TAG, "RecvFileCmd.run() -- Recv Pakcet Created!");
			
		//	LogUtil.i(TAG, "RecvFileCmd.run() -- Begin Receiving...");
			while(!isStop)
			{
				try
				{
					so_in.receive(pkt_in);
			//		LogUtil.i(TAG, "RecvFileCmd.run() -- receiv() returned!");
					LogUtil.i(TAG, "RecvFileCmd.run() -- Recv PacketLength(" + pkt_in.getLength() + ")");
				
					// Check Packet Length
					int recvLength = pkt_in.getLength();
					if(recvLength < packetHeaderLength)
					{
						LogUtil.i(TAG, "RecvFileCmd.run() -- Received bad Packet, Length=" + recvLength);
						continue;
					}
					
					// Analyse the Packet Header
					byte[] buf_recv = pkt_in.getData();
					assert(buf_recv.length == recvLength);
					ByteArrayInputStream baInPacketHeader = new ByteArrayInputStream(buf_recv, 0, packetHeaderLength);
					DataInputStream dInHeader = new DataInputStream(baInPacketHeader);
					byte stx = dInHeader.readByte();
					 cmdID = dInHeader.readShort();
					 timestamp = dInHeader.readInt();
					 tickCount = dInHeader.readInt();
					byte[] buf_temp = new byte[recvLength];
					byte[] buf_in1 = new byte[GData.maxPacketLength];
					dInHeader.read(buf_temp, 0, deviceIDLength);
					String deviceID = new String(buf_temp, 0, deviceIDLength,RecvBase.charset).trim();
					dInHeader.skipBytes(packetHeaderReservedLength);
					short dataLength = dInHeader.readShort();
					
					// Check & LogUtil
					if(stx != STX_SERVER2CLIENT || dataLength + packetHeaderLength != recvLength)
					{
						LogUtil.i(TAG, "RecvFileCmd.run() -- Received BAD Packet, stx=" + stx + " cmdID=" + cmdID + 
								" timestamp=" + timestamp + "tickCount=" + tickCount + " deviceID=" + deviceID + " recvLength=" + recvLength);
						continue;
					}
					LogUtil.i(TAG, "RecvFileCmd.run() -- Received File Packet, stx=" + stx + " cmdID=" + cmdID + 
							" timestamp=" + timestamp + "tickCount=" + tickCount + " deviceID=" + deviceID + " recvLength=" + recvLength);

					// Get server address
					 inetAddr_in = pkt_in.getAddress();
					String ip_in = inetAddr_in.getHostAddress();
					int port_in = pkt_in.getPort();
					LogUtil.i(TAG, "RecvFileCmd.run() -- Recv Packet from: IP(" + ip_in + ":" + port_in + ") Length(" + pkt_in.getLength() + ")");
					
					// Analyse Cmd Data
					switch(cmdID)
					{
					case CMD_FILE_SETCONFIG:
					{
						// Get TextData Value 
						if(dataLength != setConfigTextLength || recvLength != packetHeaderLength + setConfigTextLength)
						{
							// send nack
							String strExecDes = new String("已收到发送程序和配置变化通知指令!, 但是数据长度(" + dataLength + ") 收到长度(" + recvLength + " 错误!");
							sendAck(cmdID, timestamp, tickCount, (short)ERR_PH_DATALENGTH, (byte)0, strExecDes, so_out, inetAddr_in);      
							break;
						}
						
						ConfigFtpData ftpData = new ConfigFtpData();
						ftpData.getFtpData(buf_recv, packetHeaderLength, setConfigTextLength,cmdID);
					
						// sendAck
						String strExecDes = "已收到发送程序和配置变化通知指令!";
						boolean isFlag=true;
						if("0".equals(ftpData.getConfigFilename())&&"0".equals(ftpData.getSoftwareFilename())){
							LogUtil.i(TAG, "接收数据错误");
							strExecDes="接收数据错误!";
							isFlag=false;
						}
						sendAck(cmdID, timestamp, tickCount, (short)NET_ACK, (byte)0, strExecDes, so_out, inetAddr_in);
						if(isFlag){
							Intent myIntent = new Intent(ConstantValue.CMD_RECEIVER);  
				            myIntent.putExtra(ConstantValue.EXTRA_TYPE, cmdID);
				            myIntent.putExtra(ConstantValue.EXTRA_OBJ, ftpData);
				            myIntent.setAction(ConstantValue.CMD_RECEIVER);  
				            mContext.sendBroadcast(myIntent);  
						}
						 pkt_in.setData(buf_in1);
				           
			            
						break;
					}
					case CMD_FILE_SETLIST:
					{
						if(dataLength != setListTextLength || recvLength != packetHeaderLength + setListTextLength)
						{
							// send nack
							String strExecDes = new String("I have Received CMD_FILE_SETLIST CMD, but dataLength(" + dataLength + ") RecvLength(" + recvLength + " Error!");
							sendAck(cmdID, timestamp, tickCount, (short)ERR_PH_DATALENGTH, (byte)0, strExecDes, so_out, inetAddr_in);      
							break;
						}
						
						ConfigFtpData ftpData = new ConfigFtpData();
						ftpData.getFtpData(buf_recv, packetHeaderLength, setListTextLength,cmdID);
						// sendAck
//						inetAddr_in=InetAddress.getByName("192.168.1.196");  port_server
						boolean flag=UserInfoSingleton.getBoolean(CookieConstants.IsDownload,false);
					
			        	String strExecDes = new String("已经收到播放列表!");
			        	if(!flag){
			        		progress=0;
			        		//尚未处于下载状态
			        		sendAck(cmdID, timestamp, tickCount, (short)NET_ACK,(byte)0, strExecDes, so_out, inetAddr_in);
			        		so_out_temp=so_out;
			        		inetAddr_in_temp=inetAddr_in;
			        		pkt_in.setData(buf_in1);
				        	
				            Intent myIntent = new Intent(ConstantValue.CMD_RECEIVER);  
				            myIntent.putExtra(ConstantValue.EXTRA_TYPE, cmdID);
				            myIntent.putExtra(ConstantValue.EXTRA_OBJ, ftpData);
				            myIntent.setAction(ConstantValue.CMD_RECEIVER);  
				            mContext.sendBroadcast(myIntent);  
				            
//				            sendAck(cmdID, timestamp, tickCount, (short)NET_DOWNLOADPROGRESS, (byte)1, strExecDes, so_out, inetAddr_in);
//				            Thread.sleep(50);
//				            sendAck(cmdID, timestamp, tickCount, (short)NET_DOWNLOADPROGRESS, (byte)50, strExecDes, so_out, inetAddr_in);
//				            sendAck(cmdID, timestamp, tickCount, (short)1, (byte)100, strExecDes, so_out, inetAddr_in);
				            new Thread(new Runnable() {
				            	int temp=0;
								@Override
								public void run() {
									String strExecDes = new String("已经收到播放列表!");
									  while(true){
										  	if(temp!=progress){
										  		sendAck(cmdID, timestamp, tickCount, (short)NET_DOWNLOADPROGRESS, (byte)progress, strExecDes, so_out_temp, inetAddr_in_temp,port_server);
								            	temp=progress;
								            	LogUtil.i(TAG, "~~~~~~~~~~~~~~~~~~~~~~上传进度：progress("+progress+")");
								            	if(progress>=100){
								            		break;
								            	}
										  	}
							            	try {
												Thread.sleep(100);
											} catch (InterruptedException e) {
												// TODO Auto-generated catch block
												e.printStackTrace();
											}
							            }
							        	
								}
							}).start();
				          
			        	}else{
							//处于下载状态
							sendAck(cmdID, timestamp, tickCount, (short)NET_LIST_LOCKED,(byte)0, strExecDes, so_out, inetAddr_in);
						
						}
			        	
			        
			            
						break;
					}
					case CMD_FILE_GETLOG:
						if(dataLength != getLogTextLength || recvLength != packetHeaderLength + getLogTextLength)
						{
							// send nack
							String strExecDes = new String("I have Received CMD_FILE_GETLOG CMD, but dataLength(" + dataLength + ") RecvLength(" + recvLength + " Error!");
							sendAck(cmdID, timestamp, tickCount, (short)ERR_PH_DATALENGTH, (byte)0, strExecDes, so_out, inetAddr_in);      
							break;
						}
						
						ConfigFtpData ftpData = new ConfigFtpData();
						ftpData.getFtpData(buf_recv, packetHeaderLength, getLogTextLength,cmdID);
						LogUtil.i(TAG, "RecvFileCmd.run() -- Recv Packet " + ftpData.toString1());

						// sendAck
						String strExecDes = new String("已收到上传日志的指令!");
						sendAck(cmdID, timestamp, tickCount, (short)NET_ACK, (byte)0, strExecDes, so_out, inetAddr_in);

						Intent myIntent = new Intent(ConstantValue.CMD_RECEIVER);  
			            myIntent.putExtra(ConstantValue.EXTRA_TYPE, cmdID);
			            myIntent.putExtra(ConstantValue.EXTRA_OBJ, ftpData);
			            myIntent.setAction(ConstantValue.CMD_RECEIVER);  
			            mContext.sendBroadcast(myIntent);  
			            
			            pkt_in.setData(buf_in1);
						break;
					default:
					{
						sendAck(cmdID, timestamp, tickCount, (short)ERR_PH_CMDID, (byte)0, new String("Unknown Cmd_ID"), so_out, inetAddr_in);
					}}
				}
				catch(IOException e)
				{
//					LogUtil.e(TAG, "RecvFileCmd.run() --  catch IOException: receive() " ,e);
				}
				finally
				{
//					LogUtil.i(TAG, "RecvFileCmd.run() -- finally !!");
				}
			}
			so_in.close();
	        so_out.close();
		}
		catch (SocketException e)
		{ 
			LogUtil.e(TAG, "RecvFileCmd.run() -- catch SocketException: " ,e);
        }
		catch(Exception e)
		{
			LogUtil.e(TAG, "RecvFileCmd.run() -- catch Exception: " ,e);
		}
		finally
		{
		}	
		LogUtil.i(TAG, "RecvFileCmd.run() -- exit!");	
	}

	
	public  void sendProgress(int progress){
		try{
			String strExecDes = new String("已经收到播放设备更新软件和配置命令!");
			sendAck((short)CMD_FILE_SETLIST, timestamp, tickCount, (short)NET_DOWNLOADPROGRESS, (byte)progress, strExecDes, so_out, inetAddr_in);
			
		}catch(Exception e){
			LogUtil.e(TAG, "sendProgress -- catch Exception: " ,e);
		}
		
	}
	

	//q：
	@SuppressLint("HandlerLeak")
	private final Handler mHandler=new Handler(){

		@Override
		public void handleMessage(Message msg) {
			
			// sendAck
			Bundle bundle=msg.getData();
			int progress=bundle.getInt(ConstantValue.EXTRA_TYPE, 0);
			sendProgress(progress);
			super.handleMessage(msg);
		}
		
	};

	
}
